001    /*
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: 2002-9-6
005     * Time: 15:00:07
006     * To change template for new class use 
007     * Code Style | Class Templates options (Tools | IDE Options).
008     */
009    package EVolve.util.overlappers;
010    
011    import EVolve.visualization.*;
012    import EVolve.visualization.Dimension;
013    import EVolve.*;
014    import EVolve.exceptions.NoDataPlotException;
015    import EVolve.util.Magnifier;
016    import EVolve.data.*;
017    import javax.swing.*;
018    import javax.imageio.ImageWriter;
019    import javax.imageio.ImageIO;
020    import java.util.*;
021    import java.awt.*;
022    import java.awt.image.BufferedImage;
023    import java.awt.event.*;
024    import java.io.File;
025    import java.io.IOException;
026    
027    public abstract class OverlapVisualization {
028        protected JDialog dialog;
029        protected JScrollPane panel;
030        protected AxesPanel canvas;
031        protected ArrayList visualizationList;
032        private String xAxisName,yAxisName;
033        protected EVolve.Window window;
034        protected long xMax;
035        protected ArrayList colorList;
036        protected HashSet[] fullEntitySet;
037        protected boolean noEntityAvailable;
038    
039        private JPopupMenu popup;
040        private JMenu menuSort;
041        private JMenuItem[][] itemSort;
042        private JMenu[] menuDimension;
043        private JMenuItem itemSave, itemScale;
044        private ArrayList refLocation;
045        private Magnifier magnifier;
046        private AutoImage overlappedImage;
047        private boolean shift_pressed;
048    
049    
050        public abstract void createDialog();
051    
052        public abstract boolean isOverlapable(Visualization visualToBeOverlapped);
053    
054        public abstract void overlappedVisualize();
055    
056        public OverlapVisualization() {
057            visualizationList = new ArrayList();
058    
059            fullEntitySet = new HashSet[2];
060            fullEntitySet[0] = null;
061            fullEntitySet[1] = null;
062            noEntityAvailable = false;
063            shift_pressed = false;
064    
065            panel = createPanel();
066            addPopupTrigger(canvas);
067        }
068    
069        public void showWindow() {
070            createDialog();
071            Scene.getUIManager().showDialog(dialog, dialog.getWidth(), dialog.getHeight());
072        }
073    
074        public void newOverlappedVisualization(OverlapVisualization oVisual) {
075            Visualization visual = (Visualization)visualizationList.get(0);
076            xAxisName = visual.getDimension()[0].getName();
077            yAxisName = visual.getDimension()[1].getName();
078            window = Scene.getUIManager().addOverlappedVisualization(oVisual);
079            createMenu();
080        }
081    
082        public JPanel getPanel() {
083            return canvas;
084        }
085    
086        private JScrollPane createPanel() {
087            canvas = new AxesPanel(AxesPanel.Axis_Enabled | AxesPanel.Flip_Image | AxesPanel.Scale_Image);
088            JScrollPane returnVal = new JScrollPane(canvas);
089    
090            magnifier = new Magnifier(true);
091            canvas.addMouseMotionListener(new MouseMotionAdapter() {
092                public void mouseMoved(MouseEvent e) {
093                    if (e.isShiftDown()) shift_pressed = true;
094                    else shift_pressed = false;
095    
096                    if (e.isControlDown()) {
097                        int x = canvas.getImageX(e.getX());
098                        int y = canvas.getImageY(e.getY());
099                        magnifier.convertMousePosition(canvas);
100                        magnifier.showWindow(canvas.getSubImage(x,y));
101                        canvas.drawZoomingArea(e.getX(),e.getY());
102                    }
103                    mMoved(e.getX(), e.getY());
104                }
105            });
106    
107            canvas.addMouseMotionListener(new MouseMotionAdapter() {
108                public void mouseDragged(MouseEvent e) {
109                    mMoved(e.getX(), e.getY());
110                }
111            });
112    
113            return returnVal;
114        }
115    
116        private void mMoved(int x, int y) {
117            int xIndex = canvas.getImageX(x);
118            int yIndex = canvas.getImageY(y);
119    
120            if (noEntityAvailable) {
121                Scene.setStatus("No entity information available when temporal viz overlapped.");
122            } else {
123                try {
124                    if (shift_pressed && (getOverlappedSortedColor(xIndex,yIndex)==null)) {
125                        Scene.setStatus("  ");
126                        return;
127                    }
128    
129                    if (fullEntitySet[0].size() == 0) {
130                        String hint = getEntityName(1,yIndex);
131                        if (hint != null) {
132                            Scene.setStatus(hint);
133                        }
134                    } else {
135                        String xHint = getEntityName(0,xIndex), yHint = getEntityName(1, yIndex);
136    
137                        if ((xHint != null) && (yHint != null)) {
138                            Scene.setStatus("X: " + xHint + "   Y: " + yHint);
139                        }
140                    }
141                } catch (Exception e) {
142                    System.out.println("Exception");
143                }
144            }
145        }
146    
147        private void createMenu() {
148            popup = new JPopupMenu();
149    
150            menuSort = new JMenu("Sort");
151            menuSort.setMnemonic(KeyEvent.VK_S);
152            menuSort.setEnabled(false);
153            popup.add(menuSort);
154    
155            ArrayList tempList = new ArrayList();
156            Visualization visual = (Visualization)visualizationList.get(visualizationList.size()-1);
157            EVolve.visualization.Dimension [] dimension = visual.getDimension();
158            refLocation = new ArrayList();
159            for (int i = 0; i < dimension.length; i++) {
160                if (dimension[i] instanceof ReferenceDimension) {
161                    tempList.add(new Integer(i));
162                    refLocation.add(new Integer(i));
163                }
164            }
165    
166            ReferenceDimension[] referenceDimension = new ReferenceDimension[tempList.size()];
167            menuDimension = new JMenu[tempList.size()];
168            itemSort = new JMenuItem[tempList.size()][];
169            for (int i = 0; i < tempList.size(); i++) {
170                int j = ((Integer)(tempList.get(i))).intValue();
171                referenceDimension[i] = (ReferenceDimension)(dimension[j]);
172                menuDimension[i] = new JMenu(visual.getDefinition().getDimensionDefinition()[j].getName());
173                menuSort.add(menuDimension[i]);
174            }
175    
176            for (int i = 0; i < referenceDimension.length; i++) {
177                ArrayList comparatorList = referenceDimension[i].getComparator();
178                itemSort[i] = new JMenuItem[comparatorList.size()];
179                menuDimension[i].removeAll();
180                for (int j = 0; j < itemSort[i].length; j++) {
181                    itemSort[i][j] = new JMenuItem(((EntityComparator)(comparatorList.get(j))).getName());
182                    itemSort[i][j].addActionListener(new ActionListener() {
183                        public void actionPerformed(ActionEvent e) {
184                            selectComparator(e);
185                        }
186                    });
187                    menuDimension[i].add(itemSort[i][j]);
188                }
189            }
190    
191            itemScale = new JMenuItem("Restore");
192            itemScale.setMnemonic(KeyEvent.VK_R);
193            itemScale.addActionListener(new ActionListener() {
194                public void actionPerformed(ActionEvent e) {
195                    if (e.getActionCommand().charAt(0) == 'F') {
196                        canvas.scaleImage(true);
197                        itemScale.setText("Restore");
198                        itemScale.setActionCommand("Restore");
199                        itemScale.setMnemonic(KeyEvent.VK_R);
200                    } else {
201                        canvas.scaleImage(false);
202                        itemScale.setText("Fit Window");
203                        itemScale.setActionCommand("Fit Window");
204                        itemScale.setMnemonic(KeyEvent.VK_F);
205                    }
206                    canvas.repaint();
207                }
208            });
209            itemScale.setSelected(true);
210            popup.add(itemScale);
211    
212            itemSave = new JMenuItem("Save...");
213            itemSave.setMnemonic(KeyEvent.VK_V);
214            itemSave.addActionListener(new ActionListener() {
215                public void actionPerformed(ActionEvent e) {
216                    save();
217                }
218            });
219            popup.add(itemSave);
220        }
221    
222        protected void showPopup(MouseEvent e) {
223            popup.show(e.getComponent(), e.getX(), e.getY());
224        }
225    
226        protected void addPopupTrigger(Component component) {
227            component.addMouseListener(new MouseAdapter() {
228                public void mouseReleased(MouseEvent e) {
229                    if (e.isPopupTrigger()) {
230                        showPopup(e);
231                    }
232                }
233    
234                public void mousePressed(MouseEvent e) {
235                    if (e.isPopupTrigger()) {
236                        showPopup(e);
237                    }
238                }
239            });
240        }
241    
242        protected void enableSortMenu() {
243            menuSort.setEnabled(true);
244            Scene.getUIManager().enableFileMenus();
245        }
246    
247        protected String getColorHex(Color color) {
248            String returnVal = Integer.toHexString(color.getBlue());
249            if (returnVal.length() < 2) {
250                returnVal = "0" + returnVal;
251            }
252            returnVal = Integer.toHexString(color.getGreen()) + returnVal;
253            if (returnVal.length() < 4) {
254                returnVal = "0" + returnVal;
255            }
256            returnVal = Integer.toHexString(color.getRed()) + returnVal;
257            if (returnVal.length() < 6) {
258                returnVal = "0" + returnVal;
259            }
260    
261            return returnVal;
262        }
263    
264        private void save() {
265            BufferedImage image = new BufferedImage(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_INT_RGB);
266            canvas.paint(image.getGraphics());
267            ImageWriter writer = (ImageWriter)(ImageIO.getImageWritersByFormatName("png").next());
268    
269            JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastResultDir());
270    
271            if (fc.showSaveDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
272                File file = fc.getSelectedFile();
273                Scene.getUIManager().setLastResultDir(file.getPath());
274                try {
275                    writer.setOutput(ImageIO.createImageOutputStream(file));
276                    writer.write(image);
277                } catch (IOException e) {}
278            }
279    
280        }
281    
282        public AutoImage getSortImage() {
283            Visualization visual = null;
284            overlappedImage = new AutoImage();
285            ReferenceDimension sortedDimension[] = new ReferenceDimension[2];
286    
287            xMax = Integer.MIN_VALUE;
288    
289            for (int i=0; i<visualizationList.size(); i++) {
290                AutoImage image;
291                sortedDimension[0] = null;
292                sortedDimension[1] = null;
293    
294                visual = (Visualization)visualizationList.get(i);
295    
296                for (int j=0; j<2; j++) {
297                    Dimension dim = visual.getDimension()[j];
298                    if (dim instanceof ReferenceDimension)
299                        sortedDimension[j] = (ReferenceDimension)dim;
300                }
301                image = visual.getImage().getSortedImage(sortedDimension[0],sortedDimension[1]);
302                int w = image.getW();
303                int h = image.getH();
304    
305                for (int j=0; j<w; j++) {
306                    for (int k=0; k<h; k++) {
307                        if (image.getColor(j,k) == null) continue;
308    
309                        if (overlappedImage.getColor(j,k) == null )
310                            overlappedImage.setColor(j,k,image.getColor(j,k));
311                        else
312                            overlappedImage.setColor(j,k,new Color(153,0,153));
313                    }
314                }
315                visual.visualize();
316                if (xMax < visual.getxMax()) xMax = visual.getxMax();
317            }
318    
319            String[] comparatorName = new String[2];
320            for (int i=0; i<2; i++) {
321                if (visual.getDimension()[i] instanceof ReferenceDimension) {
322                    comparatorName[i] = ((ReferenceDimension)visual.getDimension()[i]).getSelectedComparatorName();
323                } else {
324                    comparatorName[i] = "";
325                }
326            }
327    
328            visual = (Visualization)visualizationList.get(0);
329    
330            canvas.setName(timeHeader(visual.getDimension()[0]) + xAxisName + " (" + ((fullEntitySet[0].size() == 0) ? xMax : fullEntitySet[0].size())+
331                                       ((comparatorName[0].length()==0) ? "" : ", "+ comparatorName[0]) + ")",
332                                       timeHeader(visual.getDimension()[1]) + yAxisName + " (" + fullEntitySet[1].size() +
333                                       ((comparatorName[1].length()==0) ? "" : ", "+ comparatorName[1]) + ")");
334            return overlappedImage;
335        }
336    
337        public void sort() {
338            try {
339                canvas.setImage(getSortImage().getImage());
340                canvas.repaint();
341            } catch (NoDataPlotException e) {
342                Scene.showErrorMessage(e.getMessage());
343            }
344        }
345    
346        private void selectComparator(ActionEvent e) {
347            for (int i = 0; i < itemSort.length; i++) {
348                for (int j = 0; j < itemSort[i].length; j++) {
349                    if (itemSort[i][j] == e.getSource()) {
350                        if (itemSort[i][j].getText().equals("Temporal")) {
351                            noEntityAvailable = true;
352                        } else {
353                            noEntityAvailable = false;
354                        }
355                        for (int k=0; k<visualizationList.size(); k++) {
356                            Visualization visual = (Visualization)visualizationList.get(k);
357                            ReferenceDimension ref = (ReferenceDimension)visual.getDimension()[((Integer)refLocation.get(i)).intValue()];
358                            ref.selectComparator(j);
359                        }
360                        sort();
361                        return;
362                    }
363                }
364            }
365        }
366    
367        public void unregisterOverlappedVisualization(Visualization visual) {
368            for (int i=0;i<visualizationList.size();i++) {
369                if (((Visualization)visualizationList.get(i)).getVisualizationID() == visual.getVisualizationID()) {
370                    visualizationList.remove(i);
371                }
372            }
373            if (visualizationList.size() ==1) visualizationList.clear();
374        }
375    
376        private String getEntityName(int dim,int index) {
377            Entity entity = null;
378            for (int i=0; i<visualizationList.size(); i++) {
379                Visualization visual = (Visualization)visualizationList.get(i);
380                if (!(visual.getDimension()[dim] instanceof ReferenceDimension)) return null;
381                ReferenceDimension ref = (ReferenceDimension)visual.getDimension()[dim];
382                entity = ref.getEntity(index);
383                if (entity != null) {
384                    break;
385                }
386            }
387    
388            return (entity == null) ? null : entity.getName();
389        }
390    
391        private Color getOverlappedSortedColor(int x, int y) {
392            Color returnVal = null;
393            ReferenceDimension sortedDimension[] = new ReferenceDimension[2];
394            for (int i=0; i<visualizationList.size(); i++) {
395                Visualization visual = (Visualization)visualizationList.get(i);
396                for (int j=0; j<2; j++) {
397                    Dimension dim = visual.getDimension()[j];
398                    if (dim instanceof ReferenceDimension)
399                        sortedDimension[j] = (ReferenceDimension)dim;
400                }
401                returnVal = visual.getImage().getSortedColor(sortedDimension[0],sortedDimension[1],x,y);
402                if (returnVal != null) break;
403            }
404    
405            return returnVal;
406        }
407    
408        private String timeHeader(Dimension dim) {
409            String property[] = dim.getDataFilter().getProperty();
410    
411            if (property == null) return "";
412    
413            for (int i=0; i<property.length; i++) {
414                if (property[i].equals("time"))
415                    return "Time - ";
416            }
417            return "";
418        }
419    
420        public void cleanup() {
421            fullEntitySet = null;
422            itemSort = null;
423            menuDimension = null;
424            magnifier.cleanup();
425        }
426    }